package com.atguigu.crowd.handler;

import com.atguigu.crowd.api.MySQLRemoteService;
import com.atguigu.crowd.api.RedisRemoteService;
import com.atguigu.crowd.config.ShortMessageProperties;
import com.atguigu.crowd.constant.CrowdConstant;
import com.atguigu.crowd.entity.po.MemberPo;
import com.atguigu.crowd.entity.vo.MemberLoginVo;
import com.atguigu.crowd.entity.vo.MemberVo;
import com.atguigu.crowd.util.CrowdUtil;
import com.atguigu.crowd.util.ResultEntity;
import com.netflix.discovery.converters.Auto;
import com.sun.net.httpserver.HttpsServer;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Controller
public class Memberhandler {

    @Autowired
    private ShortMessageProperties shortMessageProperties;

    @Autowired
    private RedisRemoteService redisRemoteService;

    @Autowired
    private MySQLRemoteService mySQLRemoteService;

    @RequestMapping("/auth/member/logout")
    public String logout(HttpSession session){
        session.invalidate();
            // templates目录下的内容不能直接访问，/index.html或/index都不行
        return "redirect:/";
    }

    @RequestMapping("auth/member/do/login")
    public String login(@RequestParam("loginacct") String loginacct,
                        @RequestParam("userpswd") String userpswdForm,
                        ModelMap modelMap,
                        HttpSession session) {
        ResultEntity<MemberPo> memberPoResultEntity = mySQLRemoteService.getMemberByLoginAcctRemote(loginacct);

        if (ResultEntity.FAILED.equals(memberPoResultEntity.getResult())) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,  CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "merber-login";
        }

        MemberPo memberPo = memberPoResultEntity.getData();
        String userpswdData = memberPo.getUserpswd();

        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
                                                        //原密码      经过加密的数据库里的密码
        boolean matches = bCryptPasswordEncoder.matches(userpswdForm, userpswdData);

        if (!matches) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_LOGIN_FAILED);
            return "merber-login";
        }
        MemberLoginVo memberLoginVo = new MemberLoginVo(memberPo.getId(),memberPo.getUsername(),memberPo.getEmail());

        session.setAttribute(CrowdConstant.ATTR_NAME_LOGIN_MEMBER, memberLoginVo);

        return "redirect:http://localhost/auth/member/to/center/page";
    }


    @RequestMapping("auth/do/member/register")
    public String register(MemberVo memberVo, ModelMap modelMap) {
        // 1.获取用户输入的手机号
        String phoneNum = memberVo.getPhoneNum();
        // 2.拼Redis中存储验证码的Key
        String key = CrowdConstant.REDIS_CODE_PREFIX + ":" + phoneNum;
        // 3.从Redis读取Key对应的value
        ResultEntity<String> redisResultEntity = redisRemoteService.getRedisStringValueByKey(key);
        // 4.检查查询操作是否有效
        String redisResult = redisResultEntity.getResult();
        if (ResultEntity.FAILED.equals(redisResult)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, redisResultEntity.getMessage());
            return "member-reg";
        }
        String redisCode = redisResultEntity.getData();
        if (redisCode == null) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_NOT_EXISTS);
            return "member-reg";
        }
        // 5.如果从Redis能够查询到value则比较表单验证码和Redis验证码
        String formCode = memberVo.getCode();
        if (!Objects.equals(redisCode, formCode)) {
            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE, CrowdConstant.MESSAGE_CODE_INVALID);
            return "member-reg";
        }
        // 6.如果验证码一致，则从Redis删除
        redisRemoteService.removeRedisKeyRemote(key);
        // 7.执行密码加密
        BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();
        String encode = bCryptPasswordEncoder.encode(memberVo.getUserpswd());
        memberVo.setUserpswd(encode);
        // 8.执行保存
        MemberPo memberPo = new MemberPo();
        BeanUtils.copyProperties(memberVo, memberPo);
        mySQLRemoteService.saveMember(memberPo);
//        if (ResultEntity.FAILED.equals(saveMemberResultEntity.getResult())){
//            modelMap.addAttribute(CrowdConstant.ATTR_NAME_MESSAGE,saveMemberResultEntity.getMessage());
//        }

        //使用重定向避免刷新浏览器导致重新执行注册流程
        return "redirect:/auth/member/to/login/page";
    }


    @ResponseBody
    @RequestMapping("auth/member/send/short/message.json")
    public ResultEntity<String> sendMessage(@RequestParam("phoneNum") String phoneNum) {


//1.发送验证码到phoneNum手机
//2.判断短信发送结果
//3.如果发送成功，则将验证码存入Redis

        ResultEntity<String> sendMessageResultEntity = CrowdUtil.sendShortMessage(
                shortMessageProperties.getHost(),
                shortMessageProperties.getPath(),
                shortMessageProperties.getMethod(),
                phoneNum,
                shortMessageProperties.getAppCode(),
                shortMessageProperties.getSign(),
                shortMessageProperties.getSkin()
        );
        if (ResultEntity.SUCCESS.equals(sendMessageResultEntity.getResult())) {
            String code = sendMessageResultEntity.getData();

            String key = CrowdConstant.REDIS_CODE_PREFIX + ":" + phoneNum;

            ResultEntity<String> saveCodeResultEntity = redisRemoteService.setRedisKeyValueRemoteWithTimeout(key, code, 15, TimeUnit.MINUTES);
            if (ResultEntity.SUCCESS.equals(saveCodeResultEntity.getResult())) {
                return ResultEntity.successWithoutData();
            } else {
                return saveCodeResultEntity;
            }
        } else {
            return sendMessageResultEntity;
        }

    }

}
